#include "stdafx.h"
#include "server.h"
#include "common.h"
#include "somedef.h"
#include "good.h"
#include "game.h"
#include "hook.h"
#include "utils.h"
#include "thread.h"

extern char    PipeBuffer[PIPE_BUFSIZE];

BOOL RunServerThreadFlag = TRUE;
DWORD threadId;
BOOL WINAPI StartServer(){
	CreateThread(NULL,0,ThreadMessageThread,0,0,&threadId);
	CreateThread(NULL,0,BackendScanThread,0,0,0);
	SomeData sd;
	ZeroMemory(&sd,sizeof(SomeData));
	ReadSomeData(&sd);
	sd.dnfThreadId = threadId;
	WriteSomeData(&sd);
	return TRUE;
}

VOID WINAPI StopServer(){
	RunServerThreadFlag = FALSE;
}

DWORD WINAPI StartServerThread( LPVOID pParam ){
   BOOL   fConnected = FALSE; 
   DWORD  dwThreadId = 0; 
   HANDLE hPipe = INVALID_HANDLE_VALUE, hThread = NULL; 
   DWORD pid = GetCurrentProcessId();
   TCHAR lpszPipename[MAX_PATH];
 
   _stprintf_s(lpszPipename,MAX_PATH,TEXT("\\\\.\\pipe\\PIPE%X"),pid);

   hPipe = CreateFile( 
         lpszPipename,   // pipe name 
         GENERIC_READ |  // read and write access 
         GENERIC_WRITE, 
         0,              // no sharing 
         NULL,           // default security attributes
         OPEN_EXISTING,  // opens existing pipe 
         0,              // default attributes 
         NULL);

   if (hPipe != INVALID_HANDLE_VALUE) {
		LOG_DEBUG("Pipe Server has started,please don't start again!");
		CloseHandle(hPipe);
		return -1;
   }


   hPipe = CreateNamedPipe( 
          lpszPipename,             // pipe name 
          PIPE_ACCESS_DUPLEX,       // read/write access 
          PIPE_TYPE_MESSAGE |       // message type pipe 
          PIPE_READMODE_MESSAGE |   // message-read mode 
          PIPE_WAIT,                // blocking mode 
          PIPE_UNLIMITED_INSTANCES, // max. instances  
          PIPE_BUFSIZE,                  // output buffer size 
          PIPE_BUFSIZE,                  // input buffer size 
          0,                        // client time-out 
          NULL);                    // default security attribute 

   if (hPipe == INVALID_HANDLE_VALUE){
		int error = GetLastError();
        LOG_DEBUG("CreateNamedPipe failed, GLE=%d.\n", error); 
        return -1;
   }
   
   LOG_DEBUG("Pipe Server started.\n"); 

   while (RunServerThreadFlag) 
   { 
      LOG_DEBUG("Pipe Waiting for connected...\n"); 
      fConnected = ConnectNamedPipe(hPipe, NULL) ? 
         TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); 
 
      if (fConnected) 
      { 
         ServerProcesser(hPipe);
      }else {
		  LOG_DEBUG("Pipe connect failed.\n"); 
	  }
   } 
   LOG_DEBUG("Pipe Server stopped.\n"); 
   CloseHandle(hPipe);
   return TRUE;
}


DWORD WINAPI ThreadMessageThread( LPVOID pParam ){
	MSG msg;  
    PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);  

	LOG_DEBUG("ThreadMessageThread start");

	while(GetMessage(&msg, NULL,  0, 0))  
    {  
	  UINT m = msg.message;
	  LOG_DEBUG("ThreadMessageThread %X",m);
      switch(msg.message)  
       {  
          case MSG_DLLEXIT:
			  DllExit();
              return 0;   
          case MSG_INIT: 
			  Init();
              break;  
          case MSG_STARTKILLTHREAD:  
			  StartAllKillThread();
              break;  
		  case MSG_STOPKILLTHREAD:  
			  StopAllKillThread();
              break;  
       }  
    }  
    return 0;
}

DWORD WINAPI ServerProcesser(HANDLE hPipe){

	 if(hPipe==INVALID_HANDLE_VALUE){
		 LOG_DEBUG("ServerWorkerThread INVALID_HANDLE_VALUE.\n"); 
         return -1;
	 }

     DWORD dwLen;  

	 ReadFile(hPipe, PipeBuffer, PIPE_BUFSIZE, &dwLen, NULL);

	 if(dwLen<sizeof(Request)){
		 LOG_DEBUG("ServerProcesser ReadFile failed.\n"); 
		 goto sp_end;
	 }
	 PRequest req = (PRequest)PipeBuffer;
	 switch(req->msg){
	 case MSG_INIT:
		Init();
		break;
	 case MSG_BASEINFO:
		SendBaseInfo(hPipe);
		goto sp_end;
	 case MSG_HOOKSETMONSTERGBLOOD:
		
		break;
	 case MSG_DLLEXIT:
		DllExit();
		break;
	 case MSG_HOOKDECRYPT:
		HookDecrypt();
		break;
	 case MSG_HOOKSETBLOOD:
		HookSetBlood();
		break;
	case MSG_STARTKILLTHREAD:
		StartAllKillThread();
		break;
	case MSG_STOPKILLTHREAD:
		StopAllKillThread();
		break;
	 default:
		break;
	 }

	 Response resp;
	 resp.code = 0;
	 resp.cbData = 0;

	 WriteFile(hPipe, &resp, sizeof(Response), &dwLen, NULL);

sp_end:
	 FlushFileBuffers(hPipe);
	 DisconnectNamedPipe(hPipe);
	 return 0;
}

